function timeout (time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, time)
  })
}

class SuperTask {
  constructor(maxCount = 2) {
    this.maxCount = maxCount //最大并发数
    this.tasks = [] //任务等待队列
    this.runningCount = 0 //正在处理的任务数：因为可能部分执行完了，比如当前银行有1个柜台可以办业务，另外一个人刚走刚好是空的
  }
  //添加任务：排队+触发叫号
  add (task) {
    return new Promise((resolve, reject) => {
      this.tasks.push({ task, resolve, reject })//排队
      this.run() //触发叫号：1.任务进来了判断是否能执行（客户刚来看下是否能直接办业务） 2.有任务执行完了需要补上（某个柜台办完业务了开始叫下一个）
    })
  }
  //执行任务
  run () {
    const hasruncount = this.runningCount < this.maxCount //柜台有空位：正在任务数量小于最大并发数 （可以办事的柜台<最大并发数）
    const hasTask = this.tasks.length //有人排队：确保当前是有任务存在的
    while (hasruncount && hasTask) { //什么时候可以叫号：柜台有空位&&有人排队
      const { task, resolve, reject } = this.tasks.shift()
      console.log('task-->', task)
      this.runningCount++//人已经在柜台了
      task().then(resolve, reject) //有可能返回的不是Promise，所以需要Promise.resolve()包装一下
        .finally(() => {    //柜台1的人办理完业务了要走了：上面then调完说明已经任务结束了，需要finally做继续叫号，然后继续把任务加起来
          this.runningCount--
          this.run()
        })
    }
  }
}
const superTask = new SuperTask()
function addTask (time, name) {
  superTask
    .add(() => {
      timeout(time)
    })
    .then(() => {
      console.log(`任务${name}完成`)
    })
}
addTask(1000, 1) //1s后输出：任务1完成
addTask(1000, 2) //1s后输出：任务2完成
addTask(1000, 3) //1s后输出：任务3完成
addTask(1000, 4) //1s后输出：任务4完成
addTask(1000, 5) //1s后输出：任务5完成
//效果：等1s后执行任务1、2，再等1s执行任务3、4，再等1s执行任务5